<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' rel='stylesheet' type='text/css' />
    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' rel='stylesheet' type='text/css' />
    <script src='https://struts.apache.org/highlighter/js/shCore.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' type='text/javascript'></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all();
    </script>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>Extending Themes</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="guides.html">Guides</a>&nbsp;&gt;&nbsp;<a href="tag-developers-guide.html">Tag Developers Guide</a>&nbsp;&gt;&nbsp;<a href="struts-tags.html">Struts Tags</a>&nbsp;&gt;&nbsp;<a href="ui-tags.html">UI Tags</a>&nbsp;&gt;&nbsp;<a href="themes-and-templates.html">Themes and Templates</a>&nbsp;&gt;&nbsp;<a href="extending-themes.html">Extending Themes</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Extending Themes</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13962">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13962">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13962">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13962">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13962">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13962">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent"><p>Most often, an application may just need to override a template (see <a shape="rect" href="template-loading.html">Template Loading</a>) so that a certain control renders differently. Or, an application may need to add a new template to an existing theme. Other times, you might want to create an entirely new theme, perhaps because you are building a rich set of unique and reusable templates for your organization.</p><p>There are three ways to create new themes:</p><ul><li>Create a new theme from scratch (<strong>hard!</strong>)</li><li>Wrap an existing theme</li><li>Extend an existing theme</li></ul><h2 id="ExtendingThemes-CreatingaNewThemefromScratch">Creating a New Theme from Scratch</h2><div class="confluence-information-macro confluence-information-macro-tip"><p class="title">Keep it simple, Sam!</p><span class="aui-icon aui-icon-small aui-iconfont-approve confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>It's probably never a good idea to create a new theme from scratch. Instead, use the <a shape="rect" href="simple-theme.html">simple theme</a> as a starting point. The simple theme provides just enough foundation to make it easy to create new controls by extending or wrapping the basic controls. Before starting a new theme, be sure to review the source templates for all of the provided themes. The existing themes are your best guide to creating new themes.</p></div></div><h2 id="ExtendingThemes-WrappinganExistingTheme">Wrapping an Existing Theme</h2><p>The <a shape="rect" href="xhtml-theme.html">xhtml theme</a> provides several good examples of the "wrapping" technique. The <a shape="rect" href="simple-theme.html">simple theme</a> renders the basic control. The xhtml theme "dresses up" many of the controls by adding a header and footer.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Wrapping a control</b></div><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">&lt;#include "/${parameters.templateDir}/${parameters.expandTheme}/controlheader.ftl" /&gt;
&lt;#include "/${parameters.templateDir}/simple/xxx.ftl" /&gt;
&lt;#include "/${parameters.templateDir}/${parameters.expandTheme}/controlfooter.ftl" /&gt;
</pre>
</div></div><p>Wrapping is a great way to augment the basic HTML elements provided by the simple theme.</p><h2 id="ExtendingThemes-ExtendinganExistingTheme">Extending an Existing Theme</h2><p>One benefit of object-orientated programming is that it lets us "design by difference." We can extend an object and code only the behaviour that changes. Themes provide a similar capability. The subdirectory that hosts a theme can contain a <code>theme.properties</code> file. A <code>parent</code> entry can be added to the property file to designate a theme to extend. The <a shape="rect" href="ajax-theme.html">ajax theme</a> extends the <a shape="rect" href="xhtml-theme.html">xhtml theme</a> using this technique.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>/template/ajax/theme.properties</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">parent = xhtml
</pre>
</div></div><p>An extended theme does not need to implement every single template that the <a shape="rect" href="struts-tags.html">Struts Tags</a> expect. It only needs to implement the templates that change. The other templates are loaded from the parent template.</p><h2 id="ExtendingThemes-Specialparameters">Special parameters</h2><p><a shape="rect" class="external-link" href="http://struts.apache.org/development/2.x/struts2-core/apidocs/org/apache/struts2/components/UIBean.html">UIBean</a> provides few special parameters which can be used to build a new template (they are already used in <code>xhtml</code> and <code>css_xhtml</code> theme):</p><ul class="alternate"><li><code>templateDir</code> - current value of templateDir parameter, see <a shape="rect" href="selecting-template-directory.html">Selecting Template Directory</a></li><li><code>theme</code> - used theme, see <a shape="rect" href="selecting-themes.html">Selecting Themes</a></li><li><code>template</code> - name of the template file to use (i.e. text)</li><li><code>themeExpansionToken</code> - special token used to indicate to search for a template also in parent theme (when used with <code>&lt;#include /&gt;</code> directive)</li><li><code>expandTheme</code> - tells internal template loader mechanism to try load template from current theme and then from parent theme (and parent theme, and so on)</li></ul><p>Using <code>expandTheme</code> parameter allows to override only some parts of the theme's templates, e.g. css.ftl. You can define a new theme (set theme.properties) and override just single file.</p><p>${parameters.expandTheme} is a recurrence which tells ThemeManager to load template from current theme and then from parent theme (defined in theme.properties) and so on.</p><p>Please also notice that the ThemeManager builds list of possible templates based on current theme and inherited themes (/template/custom/textarea.ftl, /template/xhtml/textarea.ftl, /template/simple/textarea.ftl). This is also true for templates which are loaded via&#160;${parameters.expandTheme}.</p><p><img class="emoticon emoticon-tick" src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/check.png" data-emoticon-name="tick" alt="(tick)"> See also example&#160;<a shape="rect" href="struts-2-themes.html">Struts 2 Themes</a> or&#160;<a shape="rect" class="external-link" href="http://www.vitarara.org/cms/struts_2_cookbook/creating_a_theme" rel="nofollow">Creating a Theme in Struts 2</a> (Mark Menard)</p></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
